package structures.review.queue;

import java.util.Scanner;

public class CircleQueueDemo {
    public static void main(String[] args) {
        CircleQueue<Integer> circleQueue = new CircleQueue<>();

        char key = ' ';
        Scanner scanner = new Scanner(System.in);
        boolean loop = true;
        while (loop) {
            System.out.println();
            System.out.println("s(show) 显示队列全部数据");
            System.out.println("e(exit) 退出程序");
            System.out.println("a(add) 添加数据");
            System.out.println("l(length) 获取长度");
            System.out.println("h(head) 查看头部数据");
            key = scanner.next().charAt(0);
            switch (key) {
                case 's':
                    circleQueue.list();
                    break;
                case 'e':
                    scanner.close();
                    loop = false;
                    break;
                case 'a':
                    circleQueue.addData(scanner.nextInt());
                    break;
                case 'h':
                    System.out.println(circleQueue.popData());
                    break;
                case 'l':
                    System.out.println(circleQueue.length());
                    break;
            }
            System.out.println("------------------------");
        }
    }
}

class CircleQueue<T> {
    private int front;
    private int rear;
    private Object dataArray[];
    private int maxSize;
    private static final int DEFAULT_SIZE = 5;

    // 为空的条件    front == rear
    // 满的条件     (rear + 1) % size == front
    // 长度   maxsize - front + rear

    public CircleQueue() {
        this(DEFAULT_SIZE);
    }

    public CircleQueue(int maxSize) {
        if (maxSize <= 0) {
            throw new IllegalArgumentException("maxSize 需要 大于 0");
        }
        this.maxSize = maxSize;
        dataArray = new Object[maxSize];
    }

    /**
     * 判空
     *
     * @return true/false
     */
    public boolean isEmpty() {
        return front == rear;
    }

    /**
     * 判满
     *
     * @return true/false
     */
    public boolean isFull() {
        return (rear + 1) % maxSize == front;
    }

    /**
     * 获取queue数据长度
     *
     * @return length
     */
    public int length() {
        return (maxSize - front + rear) % maxSize;
    }

    /**
     * 添加数据
     *
     * @param data data
     */
    public void addData(T data) {
        if (isFull()) {
            throw new RuntimeException("queue已满,不能添加数据");
        }
        dataArray[rear++] = data;
        rear %= maxSize;
    }

    /**
     * 获取数据 queue首元素
     *
     * @return data
     */
    @SuppressWarnings("unchecked")
    public T popData() {
        if (isEmpty()) {
            throw new RuntimeException("queue为空,不能获取到数据");
        }
        return (T) dataArray[front++];
    }

    /**
     * 遍历
     */
    public void list() {
        for (int i = front; i < (front + length()); i++) {
            System.out.println("index: " + i % maxSize + " --> " + dataArray[i % maxSize]);
        }
    }
}
